package com.intel.factorytest.activity;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

import com.android.internal.telephony.ITelephony;
import com.intel.factorytest.cfparser.ConfigFileParseUtil;
import com.intel.factorytest.cfparser.concrete.AConfigFileParser;
import com.intel.factorytest.cfparser.concrete.PropertiesConfParser;
import com.intel.factorytest.util.PropertiesUtil;

public class CallTest2 extends BaseActivity {

    private static final int REQ_CODE_CALL = 1;
    private static final String PHONENUMBER = "CallPhoneNumber";
    private static final String PHONENUMBER_DEF = "10010";
//    private static final String PHONENUMBER_DEF = "18682488760";
//    private static final String PHONENUMBER_DEF = "15013569309";
    
    private static final int sRetryTimes = 3;
    private int retryCounter = 0;
    
    private TelephonyManager mTelephonyMgr;
    private String mPhoneNumber = PHONENUMBER_DEF;
    
    // read log
    private Process process;
    private InputStream inputstream;
    private BufferedReader bufferedreader;
    private Thread mPhoneStateListenThread;
    private boolean isStop = false;
    private Object lock = new Object();
    private int timeout = 20; // call timeout, unit: sec
    
    private PhoneStateListener matPsl = new PhoneStateListener(){
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                System.out.println("tangjun: CallTest idle...");
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                System.out.println("tangjun: CallTest ringing...");
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                System.out.println("tangjun: CallTest offhook...");
                break;
            default:
                break;
            }
        };
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTelephonyMgr = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyMgr.listen(matPsl, PhoneStateListener.LISTEN_CALL_STATE);
        
        if (isSystemTest) mPhoneNumber = getPhoneNumber();
        call(mPhoneNumber);
        
        // listen Call state
        mPhoneStateListenThread = new Thread(new LogReaderRunnable(mTelephonyMgr));
        mPhoneStateListenThread.start();
    }
    
    private void call(String phoneNumber) {
         Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
         //startActivity(intent);
         startActivityForResult(intent, REQ_CODE_CALL);
    }
    
    private String getPhoneNumber() {
        PropertiesConfParser parser = (PropertiesConfParser) ConfigFileParseUtil.getConfParserConcrete(this, AConfigFileParser.EXTENSION_PROPERTISE);
        PropertiesUtil properties = parser.getProperties(isPcba);
        return  properties.getProperty(PHONENUMBER, PHONENUMBER_DEF);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        System.out.println("tangjun CallTest onActivityResult requestCode = " + requestCode + " ,resultCode = " + resultCode);
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case REQ_CODE_CALL:
            if (resultCode == RESULT_OK) is_pass = true;
            else is_pass = false;
            
            if (!is_pass) {// retry
                if (retryCounter < sRetryTimes) {
                    System.out.println("tangjun CallTest retry Call times=" + (++retryCounter));
                    if (mPhoneStateListenThread != null && mPhoneStateListenThread.isAlive()) {
                        isStop = true;
                    }
                    
                    call(mPhoneNumber);
mPhoneStateListenThread = new Thread(new LogReaderRunnable(mTelephonyMgr));
mPhoneStateListenThread.start();
                    
                    retryCounter++;
                } else {
                    System.out.println("tangjun CallTest retry over!");
                    finish();
                }
            } else {
                finish();
            }
            
            break;

        default:
            break;
        }
    }
    
    @Override
    public void finish() {
        // stop phone listener thread
        if (mPhoneStateListenThread != null && mPhoneStateListenThread.isAlive()) {
            isStop = true;
        }
        tc.setTestResult(is_pass);
        super.finish();
    }
    
    class LogReaderRunnable implements Runnable {  
        // Telephone service
        TelephonyManager telManager;  
        
        public LogReaderRunnable(TelephonyManager telManager) {  
            this.telManager = telManager;
        } 
        
        @Override  
        public void run() { 
            synchronized (lock) {
                long timeout_start = System.currentTimeMillis();
                int callState = telManager.getCallState();  
                System.out.println("tangjun: CallTest start at " + Thread.currentThread().getName());  
                //记录拨号开始时间  
                long threadStart = System.currentTimeMillis();  
                try { 
                    // clear catlog
                    String[] clearParams = {"logcat", "-c"}; 
                    Runtime.getRuntime().exec(clearParams).destroy();
                    System.out.println("tangjun CallTest logcat clear done!");
                    
                    process = Runtime.getRuntime().exec("logcat -v time -b radio");  
                    inputstream = process.getInputStream();  
                    InputStreamReader inputstreamreader = new InputStreamReader(inputstream);  
                    bufferedreader = new BufferedReader(inputstreamreader);  
                    String str = "";  
                    long dialingStart = 0;  
                    boolean isActive = false;
                    boolean isAlert = false;  
                    
                    while ((str = bufferedreader.readLine()) != null && !CallTest2.this.isStop) {
                        long timeout_end = System.currentTimeMillis();
                        if (timeout_end - timeout_start > timeout * 1000) {
                            System.out.println("tangjun CallTest timeout, endCall....");
                            // handle for timeout
                            CallTest2.this.is_pass = true;// 对方已经响铃，只是没有接听
                            CallTest2.this.endCall(0);
                            break;
                        }
                        
                        //如果话机状态从摘机变为空闲,销毁线程  
                        if (callState == TelephonyManager.CALL_STATE_OFFHOOK  
                                && telManager.getCallState() == TelephonyManager.CALL_STATE_IDLE) {  
                            break;  
                        }  
                        // 线程运行5分钟自动销毁  
                        if (System.currentTimeMillis() - threadStart > 300000) {  
                            break;  
                        }  
                        System.out.println("tangjun: CallTest run(); " + Thread.currentThread().getName() + ":" + str);
                        // 记录GSM状态DIALING  
                        if (str.contains("GET_CURRENT_CALLS") && str.contains("DIALING")) {  
                            // 当DIALING开始并且已经经过ALERTING或者首次DIALING  
                            if (!isAlert || dialingStart == 0) {  
                                //记录DIALING状态产生时间  
                                //dialingStart = System.currentTimeMillis();  
                                dialingStart = getTimestamp(str);
                                isAlert = false;  
                            }  
                            continue;  
                        }  
                        if (str.contains("GET_CURRENT_CALLS") && str.contains("ALERTING") && !isActive) {  
                            
                            //long temp = System.currentTimeMillis() - dialingStart;  
                            long temp = getTimestamp(str) - dialingStart;
                            System.out.println("tangjun CallTest timestamp1 info: dialingStart=" + dialingStart + ", temp=" + temp);
                            isAlert = true;  
                            //这个是关键,当第一次DIALING状态的时间,与当前的ALERTING间隔时间在1.5秒以上并且在20秒以内的话  
                            //那么认为下次的ACTIVE状态为通话接通.  
                            if (temp > 1500 && temp < 20000) {  
                                isActive = true;  
                                System.out.println("tangjun: CallTest elapse " + temp + "....." + Thread.currentThread().getName());  
                            }  
                            continue;  
                        }
                        
                        if (str.contains("GET_CURRENT_CALLS") && str.contains("ACTIVE")/* && isActive*/) {
                            //long temp = System.currentTimeMillis() - dialingStart;
                            long temp = getTimestamp(str) - dialingStart;
                            System.out.println("tangjun CallTest timestamp2 info: dialingStart=" + dialingStart + ", temp=" + temp);
                            if (isActive || (temp > 1500 && temp < 20000)) {
                                System.out.println("tangjun: CallTest Call Active!");
                                isActive = false;
                                CallTest2.this.is_pass = true;
                                CallTest2.this.endCall(10);
                                break;
                            }
                        }  
                    }  
                    System.out.println("tangjun: CallTest end at " + Thread.currentThread().getName());  
                    isStop = false;
                } catch (Exception e) {  
                    // TODO: handle exception  
                }  
            }
        }  
    } 
    
    private void endCall(int afterSeconds) {
        if (afterSeconds < 0) afterSeconds = 1;
        
        System.out.println("tangjun: CallTest enter endCall()");
        ITelephony iTelephony = getITelephony();
        System.out.println("tangjun: CallTest itelephony=" + iTelephony);
        if (iTelephony != null) {
            while (afterSeconds > 0) {
                //Toast.makeText(getApplicationContext(), afterSeconds + "'s 后，通话将自动关闭！", Toast.LENGTH_SHORT).show(); // 有问题！！！
                System.out.println("tangjun CallTest " + afterSeconds + "'s 后，通话将自动关闭！");
                try {
                    Thread.sleep(1000);
                    afterSeconds--;
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            /*
            try {
                iTelephony.endCall();
                finish();
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            */
        } else {
            System.out.println("tangjun: CallTest itelephony is null");
        }
    }
    
    private ITelephony getITelephony() {
        TelephonyManager mTelephonyManager = (TelephonyManager) this.getApplicationContext().getSystemService(TELEPHONY_SERVICE);
        Class<TelephonyManager> c = TelephonyManager.class;
        Method getITelephonyMethod = null;
        try {
            getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);
            getITelephonyMethod.setAccessible(true);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        ITelephony iTelephony = null;
        try {
            iTelephony = (ITelephony) getITelephonyMethod.invoke(mTelephonyManager, (Object[]) null);
            return iTelephony;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return iTelephony;
    }
    
    /**
     * 
     * @param str format: 10-10 16:33:29.970 D/RILJ    (  840): [0246]< GET_CURRENT_CALLS  [id=1,ALERTING
     * @return
     */
    private long getTimestamp(String str) {
        long timestamp = 0;
        if (str == null) return timestamp;
        
        String[] ss = str.split(" ");
        if (ss.length < 2) return timestamp;
        
        String y = "2014";
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        StringBuilder sb = new StringBuilder();
        String pattern = sb.append(y).append("-").append(ss[0]).append(" ").append(ss[1]).toString();
        Date date = null;
        try {
            date = sdf.parse(pattern);
            return date.getTime();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return timestamp;
    }

}
